package cn.xuqiudong.console.module.timer.schedule.ddns.handler;

import cn.xuqiudong.common.base.model.BaseResponse;
import cn.xuqiudong.console.module.timer.schedule.ddns.util.CommunicationWithMainDomain;
import cn.xuqiudong.console.module.timer.schedule.ddns.util.IpUtils;
import com.aliyun.alidns20150109.models.DescribeSubDomainRecordsResponseBody;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;

/**
 * 描述: 阿里云ddns service
 * @author Vic.xu
 * @since 2022-08-01 11:17
 */
@Service
public class AliDdnsService {

    private static final Logger LOGGER = LoggerFactory.getLogger(AliDdnsService.class);

    @Value("${ali.access.key.id}")
    private String key;
    @Value("${ali.access.key.secret}")
    private String secret;

    private void post() {
        LOGGER.info("key = {}, secret = {}", key, secret);
    }


    @Resource
    private JdbcTemplate jdbcTemplate;

    public BaseResponse<String> ddns(String subDomain) {
        BaseResponse<String> ipCheck = needChange(subDomain);
        if (!ipCheck.isSuccess()) {
            return ipCheck;
        }
        AliDnsUtils instance = null;
        try {
            instance = AliDnsUtils.getInstance(key, secret);
        } catch (Exception e) {
            e.printStackTrace();
            return BaseResponse.error(e.getMessage());
        }
        String ip = ipCheck.getData();
        try {
            DescribeSubDomainRecordsResponseBody.DescribeSubDomainRecordsResponseBodyDomainRecordsRecord record =
                    instance.subDomainRecords(subDomain);
            instance.update(record, ip);
            insertLog(subDomain, record.getValue(), ip);
            return BaseResponse.success("success: " + subDomain + "  " + record.getValue() + " - > " + ip);
        } catch (Exception e) {
            LOGGER.error("Update {} Record failure", subDomain, e);
            return BaseResponse.error("failure: " + subDomain + " - > " + ip);
        }
    }

    /**
     * 判断全部是否需要重新解析域名
     */
    public BaseResponse<?> ddns() {
        LOGGER.info("ali ddns start!");
        List<String> domainList = domainList();
        if (domainList.isEmpty()) {
            LOGGER.info("domainList is empty");
            return BaseResponse.error("domainList is empty");
        }
        boolean ipHashChanged = false;
        List<String> result = new ArrayList<>();
        for (String domain : domainList) {
            BaseResponse<String> response = ddns(domain);
            if (response.isSuccess()) {
                result.add(response.getData());
                ipHashChanged = true;
            } else {
                result.add(response.getMsg());
            }
        }
        //通知主域名所在服务器重启nginx
        if (ipHashChanged) {
            CommunicationWithMainDomain.restartNginx();
        }
        return BaseResponse.success(result);
    }

    public BaseResponse<String> needChange(String subDomain) {
        try {
            DescribeSubDomainRecordsResponseBody.DescribeSubDomainRecordsResponseBodyDomainRecordsRecord
                    record = AliDnsUtils.getInstance(key, secret).subDomainRecords(subDomain);
            if (record == null) {
                LOGGER.warn("获取{}的解析信息失败", subDomain);
                return BaseResponse.error("获取" + subDomain + "的解析信息失败");
            }
            String ip = IpUtils.getIp();
            if (ip == null) {
                LOGGER.warn("获取当前{}主机ip地址失败", subDomain);
                return BaseResponse.error("获取当前" + subDomain + "主机ip地址失败");
            }
            if (ip.equals(record.getValue())) {
                LOGGER.debug("{} ip解析地址{}没有发生变化，无需重新解析", subDomain, ip);
                return BaseResponse.error(subDomain + " ip解析地址" + ip + "没有发生变化，无需重新解析");
            }
            return BaseResponse.success(ip);
        } catch (Exception e) {
            e.printStackTrace();
            return BaseResponse.error(e.getMessage());
        }

    }

    public List<String> domainList() {
        String sql = "select domain from dns_domain a where a.enable = 1 ";
        return jdbcTemplate.queryForList(sql, String.class);
    }

    public void insertLog(String domain, String before, String after) {
        String sql = "INSERT INTO dns_change_log(`domain`,`before`, `after`) VALUES (?, ?, ?)";
        jdbcTemplate.update(sql, domain, before, after);
    }
}
